package com.xiaouyudeguang.common.interceptor;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.xiaouyudeguang.common.entity.BaseModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.sql.Statement;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Properties;

@Slf4j
@Component
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
public class ResultInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object result = invocation.proceed();
        if (Objects.isNull(result)) {
            return null;
        }
        if (result instanceof ArrayList) {
            for (Object data : ((ArrayList<?>) result)) {
                if (data instanceof BaseModel) {
                    JsonNode jsonNode = ((BaseModel<?>) data).getJson();
                    if (jsonNode.size() > 0) {
                        for (Field field : data.getClass().getDeclaredFields()) {
                            field.setAccessible(true);
                            if (jsonNode.has(field.getName())) {
                                try {
                                    field.set(data, getValue(jsonNode, field));
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
            }
        }
        return result;
    }

    public static Object getValue(JsonNode jsonNode, Field field) {
        if (Boolean.class == field.getType()) {
            return jsonNode.path(field.getName()).asBoolean();
        } else if (Long.class == field.getType()) {
            return jsonNode.path(field.getName()).asLong();
        } else if (Integer.class == field.getType()) {
            return jsonNode.path(field.getName()).asInt();
        } else if (Double.class == field.getType()) {
            return jsonNode.path(field.getName()).asDouble();
        } else if (LocalDateTime.class == field.getType()) {
            return LocalDateTime.ofEpochSecond(jsonNode.path(field.getName()).asLong() / 1000, 0, ZoneOffset.ofHours(8));
        } else if (LocalDate.class == field.getType()) {
            return LocalDate.ofEpochDay(jsonNode.path(field.getName()).asLong() / 1000);
        } else if (ArrayNode.class == field.getType()) {
            return jsonNode.withArray(field.getName());
        } else if (JsonNode.class == field.getType()) {
            return jsonNode.path(field.getName());
        }
        return jsonNode.path(field.getName()).asText();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }


    @Override
    public void setProperties(Properties properties) {


    }
}